package com.firstresponder.bluetooth;

import com.firstresponder.activity.BluetoothScreen;
import com.firstresponder.activity.FirstResponder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.util.Log;
import android.bluetooth.*;

public class BluetoothService extends Service {

	private ArrayList<MacScanStatus> listMacAddress = null;
	private MacScanStatus currentDevice = null;
	private static FirstResponder MAIN_ACTIVITY = null;
	// private static BluetoothScreen MAIN_ACTIVITY2 = null;
	private static boolean SERVICE_RUNNING = false;
	private long disStartTime, disTotalTime;
	private BluetoothAdapter FrAdapter = null;
	private String locId;
	private int discoveryCounter, numOfDevices, remainingTime;
	private final String TAG = "FRBluetoothService";
	private final String destinationAddress = "9175969918";// 9738509193
	private final SmsManager smsmanager = SmsManager.getDefault();
	private TimerTask scanTask;
	private SimpleDateFormat timingFormat;
	final Handler handler = new Handler();
	private Timer t = new Timer();
	private Handler mHandler = new Handler();

	public void onCreate() {
		Log.i(TAG, "FRBluetoothService, onCreate()");
		SERVICE_RUNNING = true;
		discoveryCounter = 0;
		numOfDevices = 0;
		// Register for broadcasts when a device is discovered
		listMacAddress = new ArrayList<MacScanStatus>();
		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
		this.registerReceiver(mReceiver, filter);

		// Register for broadcasts when discovery has finished
		filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		this.registerReceiver(mReceiver, filter);
		// Get the local Bluetooth adapter
		FrAdapter = BluetoothAdapter.getDefaultAdapter();
		locId = FrAdapter.getAddress();
		// Get a set of currently paired devices
		Log.i(TAG, "FRBluetoothService, onCreate() finished");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "Discovery about to start");
		// doDiscovery();
		doBlueToothScan();
		Log.i(TAG, "Discovery finished");
		return START_STICKY;
		// return super.onStartCommand(intent, flags, startId);
	}

	public void onDestroy() {
		super.onDestroy();
		Log.i(TAG, "SERVICE IS ABOUT TO DESTROY");
		// Make sure we're not doing discovery anymore
		if (FrAdapter != null) {
			FrAdapter.cancelDiscovery();
		}
		stopScan();
		// Unregister broadcast listeners
		this.unregisterReceiver(mReceiver);
		mHandler.removeCallbacks(updateTask);
		SERVICE_RUNNING = false;
		if (MAIN_ACTIVITY != null) {
			MAIN_ACTIVITY.UpdateUI("SERVICE DESTROYED", 1);
		}
		MAIN_ACTIVITY = null;
	}

	final BroadcastReceiver mReceiver = new BroadcastReceiver() {
		PendingIntent sentIntent = null;

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			String address;
			sentIntent = PendingIntent.getService(BluetoothService.this, 0,
					intent, 0);

			/*
			 * WHEN DISCOVERY FINDS DEVICE: Send text for all NEW devices that
			 * will be recorded
			 */
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				// Get the BluetoothDevice object from the Intent
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Log.i(TAG, "Getting mac Adress");
				// ADDED FROM OTHER PROJECT
				address = device.getAddress();
				Log.i(TAG, "MAC ADDRESS FOUND" + address);
				currentDevice = new MacScanStatus(address, true);
				numOfDevices++;
				sendMessageIfNew(address);
				if (MAIN_ACTIVITY != null) {
					MAIN_ACTIVITY.UpdateUI(address, 0);
				}
			}
			/*
			 * WHEN DISCOVERY FINISHED: Compare current scanned devices with
			 * listMacAddresses and Send DELETE text for each address that is
			 * not one of the current devices.
			 */
			else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
				Log.i(TAG, "DISCOVERY FINSIHED");
				if (MAIN_ACTIVITY != null) {
					MAIN_ACTIVITY.UpdateDevices(numOfDevices);
				}
				deleteIfNotDetected();
				discoveryCounter++;// Temporarily implemented to stop the
									// service, see
				// doBlueToothScan();
				disTotalTime = System.currentTimeMillis() - disStartTime;
				updateTimer(disTotalTime);
				Log.i(TAG, "Counter is at" + discoveryCounter);
			}
		}

		private void sendMessageIfNew(String address) {
			if (!isListHolding()) {
				listMacAddress.add(currentDevice);
				timingFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String textAdd = "FR" + "#MAC=" + address + "#LOCID=" + locId
						+ "#TASK=ADD#TIME=" + timingFormat.format(new Date())
						+ "#FR";
				Log.i(TAG, "MAC ADDRESS SEND TEXT: " + textAdd);
				// smsmanager.sendTextMessage(destinationAddress, null, textAdd,
				// sentIntent, null);
			}
		}

		private void deleteIfNotDetected() {
			Iterator<MacScanStatus> it = listMacAddress.iterator();
			MacScanStatus device = null;
			while (it.hasNext()) {
				device = it.next();
				if (device.isCurrentScan() == false) {
					timingFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					timingFormat.format(new Date());
					String textDelete = "FR" + "#MAC=" + device.getMacAdress()
							+ "#LOCID=" + locId + "#TASK=DELETE#TIME="
							+ timingFormat.format(new Date()) + "#FR";
					Log.i(TAG, "MAC ADDRESS SEND TEXT: " + textDelete);

					// smsmanager.sendTextMessage(destinationAddress, null,
					// textDelete, sentIntent, null);
					it.remove();
				} else {
					Log.i(TAG, "RESET isCurrentScan TO FALSE: ");
					// Reset isCurrentScan to False in preparation for next
					// scan.
					device.setCurrentScan(false);
				}
			}
			numOfDevices = 0;
		}

	};

	private void doDiscovery() {
		// If we're already discovering, stop it
		if (FrAdapter.isDiscovering()) {
			FrAdapter.cancelDiscovery();
		}

		// Request discover from BluetoothAdapter
		FrAdapter.startDiscovery();
	}

	public void doBlueToothScan() {

		scanTask = new TimerTask() {
			public void run() {
				handler.post(new Runnable() {
					public void run() {
						Log.i(TAG, "Doing Discovery");
						if (MAIN_ACTIVITY != null) {
							MAIN_ACTIVITY.UpdateUI("Discovery "
									+ (discoveryCounter + 1) + " Started", 1);
						}
						doDiscovery();
						disStartTime = System.currentTimeMillis();
						Log.i(TAG, "Discovery Finished");
					}
				});
				/*
				 * The Service for now doesn't stop so there will be a counter
				 * for the purposes of basic proof of concept for stopping
				 * itself. Ideally the service will stop once a specific message
				 * is sent to the SMS Broadcast Reciever and it will call
				 * stopService:
				 * 
				 * if (counter > 2) { Log.i(TAG, "Service About to stop");
				 * stopSelf(); Log.i(TAG, "Service Stopped to stop"); }
				 */
			}
		};
		t.schedule(scanTask, 3, 60000);
	}

	public void stopScan() {
		if (scanTask != null) {
			Log.i("TIMER", "timer canceled");
			scanTask.cancel();
			t.cancel();
			t.purge();
			if (MAIN_ACTIVITY != null) {
				MAIN_ACTIVITY.UpdateUI("SCAN STOPPING", 1);
			}
		}
	}

	public boolean isListHolding() {
		for (MacScanStatus device : listMacAddress) {
			if (device.isAddressEqual(currentDevice.getMacAdress())) {
				// Mark the device as being found in the current scan
				device.setCurrentScan(true);
				return true;
			}
		}
		return false;
	}

	public static boolean isRunning() {
		return SERVICE_RUNNING;
	}

	public static void setIsRunning(boolean isrunning) {
		SERVICE_RUNNING = isrunning;
	}

	public void updateTimer(long disTotalTime) {
		remainingTime = (int) (60000 - disTotalTime) / 1000;
		if (MAIN_ACTIVITY != null) {
			MAIN_ACTIVITY.updateTimerText("0");
		}
		if (BluetoothService.isRunning()) {
			mHandler.postDelayed(updateTask, 100);
		}
	}

	final Runnable updateTask = new Runnable() {
		@Override
		public void run() {
			if (MAIN_ACTIVITY != null) {
				MAIN_ACTIVITY.updateTimerText(Integer.toString(remainingTime));
			}
			remainingTime--;
			if (remainingTime != -1) {
				mHandler.postDelayed(this, 1000);
			}
		}
	};

	public String getLocId() {
		return locId;
	}

	public void setLocId(String locId) {
		this.locId = locId;
	}

	public static void setMainActivity(FirstResponder activity) {
		MAIN_ACTIVITY = activity;
	}

	// public static void setMainActivityB(BluetoothScreen activity) {
	// MAIN_ACTIVITY2 = activity;
	// }

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
}
